package cn.easyplatform.studio.web.editors.project;

import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.cmd.uploadHist.SetUploadHistCmd;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.utils.*;
import cn.easyplatform.studio.vos.IXVo;
import cn.easyplatform.studio.vos.MediaFileVo;
import cn.easyplatform.studio.vos.UploadHistVo;
import cn.easyplatform.studio.web.editors.AbstractPanelEditor;
import cn.easyplatform.studio.web.editors.ComponentCallback;
import cn.easyplatform.studio.web.layout.WorkbenchController;
import cn.easyplatform.studio.web.views.impl.AbstractView;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.input.ReaderInputStream;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.zkoss.util.media.Media;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.UploadEvent;
import org.zkoss.zul.*;
import sun.misc.BASE64Decoder;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;

public class FileImportEditor extends AbstractPanelEditor {
    protected Label project;

    protected Label operator;

    protected Label date;

    protected Label size;

    protected Label comment;

    protected Listbox sources;

    protected Button commit;

    protected IXVo entity;

    public FileImportEditor(WorkbenchController workbench, String id) {
        super(workbench, id);
    }

    @Override
    protected void dispatch(Event evt) {
        if (evt.getName().equals(Events.ON_UPLOAD)) {
            UploadEvent ue = (UploadEvent) evt;
            IXVo vo = (IXVo) ZipUtil.unpackZip(ue.getMedia().getByteData());
            redraw(vo);
        } else if (evt.getName().equals(Events.ON_DOUBLE_CLICK)) {
            Listitem ti = (Listitem) evt.getTarget();
            UploadHistVo histVo = ti.getValue();
            MediaFileVo vo = new MediaFileVo();
            vo.setName(histVo.getFileName());
            vo.setType(histVo.getType());
            vo.setBase64Data(histVo.getUploadData());
            AbstractView.createFileView(new ComponentCallback(project, Labels.getLabel("editor.import.file.info")),
                    vo).doOverlapped();
        } else if (evt.getTarget().getId().equals("fileImport_button_commit")) {
            if (StudioApp.execute(new SetUploadHistCmd(entity.getFileVos())) == true) {
                for (UploadHistVo histVo: entity.getFileVos()) {
                    base64ToFile(histVo);
                }
                WebUtils.showSuccess(Labels.getLabel("export.success"));
            }
        }
    }

    @Override
    public void create(Object... args) {
        Idspace is = createPanel(Labels.getLabel("menu.repo.import.file"), "~./images/file.png",
                "~./include/editor/project/fileImport.zul");
        this.project = (Label) is.getFellow("fileImport_label_project");
        this.operator = (Label) is.getFellow("fileImport_label_operator");
        this.date = (Label) is.getFellow("fileImport_label_date");
        this.comment = (Label) is.getFellow("fileImport_label_comment");
        this.size = (Label) is.getFellow("fileImport_label_size");
        this.sources = (Listbox) is.getFellow("fileImport_listbox_sources");
        this.commit = (Button) is.getFellow("fileImport_button_commit");
        this.commit.addEventListener(Events.ON_CLICK, this);
        is.getFellow("fileImport_button_upload").addEventListener(Events.ON_UPLOAD, this);
    }

    private void redraw(IXVo vo) {
        entity = vo;
        project.setValue(vo.getProjectId());
        operator.setValue(vo.getUser());
        date.setValue(DateFormatUtils.format(vo.getDate(), "yyyy-MM-dd hh:mm:ss"));
        size.setValue((vo.getFileVos() != null ? vo.getFileVos().size(): "0") + "");
        comment.setValue(vo.getDesp());
        redrawTree(entity);
        commit.setDisabled(false);
    }

    private void redrawTree(IXVo vo) {
        sources.getItems().clear();
        if (vo.getFileVos() != null) {
            for (UploadHistVo histVo : vo.getFileVos()) {
                histVo.setPackName(vo.getProjectId());
                histVo.setProjectName(Contexts.getProject().getName());
                histVo.setUploadUser(Contexts.getUser().getName());
                Listitem li = new Listitem();
                li.appendChild(new Listcell(histVo.getFileName()));
                String typeStr = null;
                if (ServiceFileUtil.MediaType.MEDIA_TYPE_IMG.getName().equals(histVo.getType())) {
                    typeStr = Labels.getLabel("editor.file.img");
                } else if (ServiceFileUtil.MediaType.MEDIA_TYPE_VIDEO.getName().equals(histVo.getType())) {
                    typeStr = Labels.getLabel("editor.file.video");
                } else if (ServiceFileUtil.MediaType.MEDIA_TYPE_AUDIO.getName().equals(histVo.getType())) {
                    typeStr = Labels.getLabel("editor.file.audio");
                } else if (ServiceFileUtil.MediaType.MEDIA_TYPE_CSS.getName().equals(histVo.getType())) {
                    typeStr = Labels.getLabel("editor.file.css");
                } else if (ServiceFileUtil.MediaType.MEDIA_TYPE_JS.getName().equals(histVo.getType())) {
                    typeStr = Labels.getLabel("editor.file.js");
                }
                li.appendChild(new Listcell(typeStr));
                DecimalFormat df = new DecimalFormat("#.##KB");
                double size = FileUtil.base64fileSize(histVo.getUploadData()) / 1024.0;
                li.appendChild(new Listcell(df.format(size)));
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String dateString = format.format(histVo.getCreateDate());
                li.appendChild(new Listcell(dateString));
                li.setValue(histVo);
                li.addEventListener(Events.ON_DOUBLE_CLICK, this);
                sources.appendChild(li);
            }
        }
    }

    private void copyByteToFile(String pathStr, Media media) {
        try {
            String mediaPath_studio = pathStr + File.separator + media.getName();
            if ("text/css".equals(media.getContentType())) {
                byte[] bytes = null;
                try {
                    bytes = media.getByteData();
                } catch (IllegalStateException e) {
                    bytes = media.getStringData().getBytes();
                }
                FileUtils.copyInputStreamToFile(new ByteArrayInputStream(bytes), new File(mediaPath_studio));
            } else if ("text/javascript".equals(media.getContentType())) {
                try {
                    FileUtils.copyInputStreamToFile(new ReaderInputStream(media.getReaderData()), new File(mediaPath_studio));
                } catch (IllegalStateException e) {
                    FileUtils.copyInputStreamToFile(new ByteArrayInputStream(media.getByteData()), new File(mediaPath_studio));
                }
            } else {
                FileUtils.copyInputStreamToFile(media.getStreamData(), new File(mediaPath_studio));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public boolean base64ToFile(UploadHistVo histVo) {
        String pathStr = null;
        if (histVo.getType().equals(ServiceFileUtil.MediaType.MEDIA_TYPE_IMG.getName()))
            pathStr = new StudioServiceFileUtils().imgDirPath_stu;
        else if (histVo.getType().equals(ServiceFileUtil.MediaType.MEDIA_TYPE_CSS.getName()))
            pathStr = new StudioServiceFileUtils().cssDirPath_stu;
        else if (histVo.getType().equals(ServiceFileUtil.MediaType.MEDIA_TYPE_JS.getName()))
            pathStr = new StudioServiceFileUtils().jsDirPath_stu;
        else if (histVo.getType().equals(ServiceFileUtil.MediaType.MEDIA_TYPE_AUDIO.getName()))
            pathStr = new StudioServiceFileUtils().audioDirPath_stu;
        else if (histVo.getType().equals(ServiceFileUtil.MediaType.MEDIA_TYPE_VIDEO.getName()))
            pathStr = new StudioServiceFileUtils().videoDirPath_stu;
        String mediaPath_studio = pathStr + File.separator + histVo.getFileName();
        byte[] buffer;
        try {
            buffer = new BASE64Decoder().decodeBuffer(histVo.getUploadData());
            FileOutputStream out = new FileOutputStream(mediaPath_studio);
            out.write(buffer);
            out.close();
            return true;
        } catch (Exception e) {
            throw new RuntimeException("base64字符串异常或地址异常\n" + e.getMessage());
        }
    }
}
